package org.lisy.java.thread;

import java.time.Duration;
import java.time.Instant;
import java.util.concurrent.TimeUnit;

/**
 * 线程组操作
 * 
 * @author lisy
 */
public class ThreadGroupOperate {
	
	public static void main(String[] args) {
		// 构造方法初始化时未指定线程组，系统自动获取当前线程的线程组作为默认父线程组，Thread.currentThread().getThreadGroup()
		ThreadGroup group1 = new ThreadGroup("group-1");
		System.out.println("group1:" + group1.getName() + " parent:" + group1.getParent().getName());
		
		ThreadGroup group2 = new ThreadGroup(group1 ,"group-2");
		System.out.println("group2:" + group2.getName() + " parent:" + group2.getParent().getName());
		
		Thread thread1 = new Thread(group1, new MyGroupRunnable(), "thread-1");
		Thread thread2 = new Thread(group2, new MyGroupRunnable(), "thread-2");
		thread1.start();
		thread2.start();
		// activeCount() 方法可以返回线程组中的所有活动线程数，包含下面的所有子孙节点的线程，线程动态变化，这是个估算值
		System.out.println("active group thread: " + Thread.currentThread().getThreadGroup().activeCount());	
        System.out.println("active group:" + Thread.currentThread().getThreadGroup().activeGroupCount());	
        
        // 调用线程组interrupt()，会将线程组树下的所有子孙线程中断标志置为true，可以用来批量中断线程
		group1.interrupt();
		try {
			TimeUnit.SECONDS.sleep(1);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
        System.out.println("active group thread: " + Thread.currentThread().getThreadGroup().activeCount());	
        System.out.println("active group:" + Thread.currentThread().getThreadGroup().activeGroupCount());	
        
	}
}

class MyGroupRunnable implements Runnable {	
    @Override	
    public void run() {	
    	Thread thread = Thread.currentThread();
    	System.out.println("thread start: " + thread.getName());
    	// 防止 sleep interrupt 异常，循环计时完成
    	Instant instant = Instant.now();
    	while (!thread.isInterrupted()) {
    		long seconds = Duration.between(instant, Instant.now()).getSeconds();
            if (seconds >= 3) {
            	break;
            }
        }
    	System.out.println("thread end: " + thread.getName());
    }	
}
